﻿
namespace SistemaLogistica.DataAccess
{
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.Common;
    using SistemaLogistica.Business.Entities;
    using SistemaLogistica.Business.Entities.Types;

    public class SubastaData : BaseDataAccess
    {
        private SubastaData() { }

        private readonly static SubastaData instancia = new SubastaData();

        public static SubastaData Instancia
        {
            get { return instancia; }
        }

        public List<Subasta> Listar()
        {
            List<Subasta> coleccion = new List<Subasta>();
            DbCommand cmd = db.GetStoredProcCommand("GetAllFromSubasta");
            using (IDataReader dr = db.ExecuteReader(cmd))
            {
                while (dr.Read())
                {
                    coleccion.Add(new Subasta
                    {
                        Descripcion = dr.GetString(dr.GetOrdinal("Descripcion")),
                        FechaSubasta = dr.GetDateTime(dr.GetOrdinal("FechaSubasta")),
                        Hora = dr.GetString(dr.GetOrdinal("Hora")),
                        IdSubasta = dr.GetInt32(dr.GetOrdinal("IdSubasta")),
                        Lugar = dr.GetString(dr.GetOrdinal("Lugar"))
                    });
                }
            }
            return coleccion;
        }

        public List<Subasta> Buscar(DateTime fecha)
        {
            List<Subasta> coleccion = new List<Subasta>();
            DbCommand cmd = db.GetStoredProcCommand("GetSubastaByFecha");
            db.AddInParameter(cmd, "fecha", DbType.String, fecha);
            using (IDataReader dr = db.ExecuteReader(cmd))
            {
                while (dr.Read())
                {
                    coleccion.Add(new Subasta
                    {
                        Descripcion = dr.GetString(dr.GetOrdinal("Descripcion")),
                        FechaSubasta = dr.GetDateTime(dr.GetOrdinal("FechaSubasta")),
                        Hora = dr.GetString(dr.GetOrdinal("Hora")),
                        IdSubasta = dr.GetInt32(dr.GetOrdinal("IdSubasta")),
                        Lugar = dr.GetString(dr.GetOrdinal("Lugar"))
                    });
                }
            }
            return coleccion;
        }

        public Subasta ObtenerPorID(int idSubasta)
        {
            Subasta subasta = null;
            DbCommand cmd = db.GetStoredProcCommand("GetSubastaByIdSubasta");
            db.AddInParameter(cmd, "idSubasta", DbType.Int32, idSubasta);
            using (IDataReader dr = db.ExecuteReader(cmd))
            {
                while (dr.Read())
                {
                    subasta = new Subasta
                    {
                        Descripcion = dr.GetString(dr.GetOrdinal("Descripcion")),
                        FechaSubasta = dr.GetDateTime(dr.GetOrdinal("FechaSubasta")),
                        Hora = dr.GetString(dr.GetOrdinal("Hora")),
                        IdSubasta = dr.GetInt32(dr.GetOrdinal("IdSubasta")),
                        Lugar = dr.GetString(dr.GetOrdinal("Lugar")),
                        Detalle = DetalleSubastaData.Instancia.ListarPorSubasta(idSubasta)
                    };
                }
            }
            return subasta;
        }

        public int Registrar(Subasta subasta)
        {
            int idSubasta = 0, huboexito;
            using (DbConnection cnn = db.CreateConnection())
            {
                cnn.Open();
                using (DbTransaction tran = cnn.BeginTransaction())
                {
                    try
                    {
                        DbCommand cmdS = db.GetStoredProcCommand("InsertSubasta");
                        db.AddInParameter(cmdS, "descripcion", DbType.String, subasta.Descripcion);
                        db.AddInParameter(cmdS, "fechaSubasta", DbType.DateTime, subasta.FechaSubasta);
                        db.AddInParameter(cmdS, "hora", DbType.String, subasta.Hora);
                        db.AddOutParameter(cmdS, "idSubasta", DbType.Int32, 11);
                        db.AddInParameter(cmdS, "lugar", DbType.String, subasta.Lugar);
                        huboexito = db.ExecuteNonQuery(cmdS, tran);
                        if (huboexito == 0)
                        {
                            throw new Exception("Error");
                        }

                        idSubasta = int.Parse(db.GetParameterValue(cmdS, "idSubasta").ToString());

                        DbCommand cmdD = db.GetStoredProcCommand("InsertDetalleSubasta");
                        DbCommand cmdU = db.GetStoredProcCommand("UpdateEstadoBien");

                        foreach (DetalleSubasta d in subasta.Detalle)
                        {
                            db.AddInParameter(cmdD, "cantidad", DbType.Decimal, d.Cantidad);
                            db.AddInParameter(cmdD, "estado", DbType.String, d.Estado);
                            db.AddInParameter(cmdD, "idBien", DbType.Int32, d.IdBien);
                            db.AddInParameter(cmdD, "idSubasta", DbType.Int32, idSubasta);
                            db.AddInParameter(cmdD, "montoInicial", DbType.Currency, d.MontoInicial);
                            huboexito = db.ExecuteNonQuery(cmdD, tran);
                            if (huboexito == 0)
                            {
                                throw new Exception("Error");
                            }
                            cmdD.Parameters.Clear();

                            db.AddInParameter(cmdU, "idBien", DbType.Int32, d.IdBien);
                            db.AddInParameter(cmdU, "estado", DbType.Int32, (int)DisponibilidadType.NoDisponible);
                            huboexito = db.ExecuteNonQuery(cmdU, tran);
                            if (huboexito == 0)
                            {
                                throw new Exception("Error");
                            }
                            cmdU.Parameters.Clear();
                        }

                        tran.Commit();
                    }
                    catch (Exception ex)
                    {
                        tran.Rollback();
                        throw ex;
                    }
                }
            }
            return idSubasta;
        }

        public void Modificar(Subasta subasta)
        {
            int huboexito;
            using (DbConnection cnn = db.CreateConnection())
            {
                cnn.Open();
                using (DbTransaction tran = cnn.BeginTransaction())
                {
                    try
                    {
                        DbCommand cmdS = db.GetStoredProcCommand("UpdateSubasta");
                        db.AddInParameter(cmdS, "descripcion", DbType.String, subasta.Descripcion);
                        db.AddInParameter(cmdS, "fechaSubasta", DbType.DateTime, subasta.FechaSubasta);
                        db.AddInParameter(cmdS, "hora", DbType.String, subasta.Hora);
                        db.AddInParameter(cmdS, "idSubasta", DbType.Int32, subasta.IdSubasta);
                        db.AddInParameter(cmdS, "lugar", DbType.String, subasta.Lugar);
                        huboexito = db.ExecuteNonQuery(cmdS, tran);
                        if (huboexito == 0)
                        {
                            throw new Exception("Error");
                        }

                        DbCommand cmdDD = db.GetStoredProcCommand("DeleteDetalleSubastaBySubasta");
                        db.AddInParameter(cmdDD, "idSubasta", DbType.Int32, subasta.IdSubasta);
                        huboexito = db.ExecuteNonQuery(cmdDD, tran);
                        if (huboexito == 0)
                        {
                            throw new Exception("Error");
                        }

                        DbCommand cmdD = db.GetStoredProcCommand("InsertDetalleSubasta");
                        DbCommand cmdU = db.GetStoredProcCommand("UpdateEstadoBien");

                        foreach (DetalleSubasta d in subasta.Detalle)
                        {
                            db.AddInParameter(cmdD, "cantidad", DbType.Decimal, d.Cantidad);
                            db.AddInParameter(cmdD, "estado", DbType.String, d.Estado);
                            db.AddInParameter(cmdD, "idBien", DbType.Int32, d.IdBien);
                            db.AddInParameter(cmdD, "idSubasta", DbType.Int32, d.IdSubasta);
                            db.AddInParameter(cmdD, "montoInicial", DbType.Currency, d.MontoInicial);
                            huboexito = db.ExecuteNonQuery(cmdD, tran);
                            if (huboexito == 0)
                            {
                                throw new Exception("Error");
                            }
                            cmdD.Parameters.Clear();

                            db.AddInParameter(cmdU, "idBien", DbType.Int32, d.IdBien);
                            db.AddInParameter(cmdU, "estado", DbType.Int32, (int)DisponibilidadType.NoDisponible);
                            huboexito = db.ExecuteNonQuery(cmdU, tran);
                            if (huboexito == 0)
                            {
                                throw new Exception("Error");
                            }
                            cmdU.Parameters.Clear();
                        }
                        tran.Commit();
                    }
                    catch (Exception ex)
                    {
                        tran.Rollback();
                        throw ex;
                    }
                }
            }
        }

        public void Eliminar(int idSubasta)
        {
            using (DbConnection cnn = db.CreateConnection())
            {
                cnn.Open();
                using (DbTransaction tran = cnn.BeginTransaction())
                {
                    try
                    {
                        int result = 0;
                        List<DetalleSubasta> detalle = DetalleSubastaData.Instancia.ListarPorSubasta(idSubasta);

                        DbCommand cmdUpdateEstado = db.GetStoredProcCommand("UpdateEstadoBien");

                        foreach (DetalleSubasta d in detalle)
                        {
                            db.AddInParameter(cmdUpdateEstado, "idBien", DbType.Int32, d.IdBien);
                            db.AddInParameter(cmdUpdateEstado, "estado", DbType.Int32, (int)DisponibilidadType.Disponible);

                            result = db.ExecuteNonQuery(cmdUpdateEstado, tran);
                            if (result == 0) throw new Exception("Error al Actualizar Estado de Bien.");
                        }

                        DbCommand cmdSubasta = db.GetStoredProcCommand("DeleteSubasta");
                        db.AddInParameter(cmdSubasta, "idSubasta", DbType.Int32, idSubasta);

                        result = db.ExecuteNonQuery(cmdUpdateEstado, tran);
                        if (result == 0) throw new Exception("Error al Eliminar Subasta.");

                        tran.Commit();
                    }
                    catch (Exception ex)
                    {
                        tran.Rollback();
                        throw ex;
                    }
                }
            }
                        
        }
    }
}
